package org.zlpt.contract.dao;

import com.owlike.genson.Genson;
import org.hyperledger.fabric.contract.Context;
import org.hyperledger.fabric.contract.ContractInterface;
import org.hyperledger.fabric.contract.annotation.Contract;
import org.hyperledger.fabric.contract.annotation.Transaction;
import org.hyperledger.fabric.shim.ChaincodeException;
import org.hyperledger.fabric.shim.ChaincodeStub;
import org.zlpt.entity.co.ContractCO;


@Contract(
    name = "contract"
)
public final class ContractContract implements ContractInterface {
    private final Genson genson = new Genson();

    @Transaction(intent = Transaction.TYPE.EVALUATE)
    public boolean ContractExists(final Context ctx, String contractJson){
        ChaincodeStub stub = ctx.getStub();
        ContractCO contract = genson.deserialize(contractJson, ContractCO.class);
        String contractJSON = stub.getStringState(contract.formKey());

        return (contractJSON != null && !contractJSON.isEmpty());
    }

    @Transaction(intent = Transaction.TYPE.SUBMIT)
    public ContractCO CreateContract(final Context ctx, String contractJson) {
        ChaincodeStub stub = ctx.getStub();
        if (ContractExists(ctx, contractJson)) {
            String errorMessage = String.format("Contract already exists");
            System.out.println(errorMessage);
            throw new ChaincodeException(errorMessage);
        }
        ContractCO contract = genson.deserialize(contractJson, ContractCO.class);
        stub.putStringState(contract.formKey(), contractJson);
        return contract;
    }
    @Transaction(intent = Transaction.TYPE.EVALUATE)
    public ContractCO ReadContract(final Context ctx, String contractId) {
        ChaincodeStub stub = ctx.getStub();
        String keyPrefiexContractId = ContractCO.formKey(Long.valueOf(contractId));
        String contractJSON = stub.getStringState(keyPrefiexContractId);
        if (contractJSON == null || contractJSON.isEmpty()) {
            String errorMessage = String.format("Contract does not exist");
            System.out.println(errorMessage);
            throw new ChaincodeException(errorMessage);
        }

        ContractCO contract = genson.deserialize(contractJSON, ContractCO.class);
        return contract;
    }
    @Transaction(intent = Transaction.TYPE.SUBMIT)
    public ContractCO UpdateContract(final Context ctx, String contractJson) {
        ChaincodeStub stub = ctx.getStub();
        ContractCO contract = genson.deserialize(contractJson, ContractCO.class);

        if (!ContractExists(ctx, contractJson)) {
            String errorMessage = String.format("Contract does not exist");
            System.out.println(errorMessage);
            throw new ChaincodeException(errorMessage);
        }
        String oldContractJson = stub.getStringState(contract.formKey());
        ContractCO oldContract = genson.deserialize(oldContractJson, ContractCO.class);
        String sortedJson = genson.serialize(contract);
        stub.putStringState(contract.formKey(), sortedJson);
        return oldContract;
    }
    @Transaction(intent = Transaction.TYPE.SUBMIT)
    public void DeleteContract(final Context ctx, String contractId) {
        ChaincodeStub stub = ctx.getStub();

        if (!ContractExists(ctx, contractId)) {
            String errorMessage = String.format("Contract does not exist");
            System.out.println(errorMessage);
            throw new ChaincodeException(errorMessage);
        }

        stub.delState(contractId);
    }
}




